﻿using System;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace Spacer {
	public abstract class Ship : Pawn {
		public Ship() {}

		public Ship( SolarSys world ) : base(world) {
			if( this.GetType() == typeof(Ship) ) Initialize();
		}

		public override bool CreateSaveState( EntitySaveState save ) {
			base.CreateSaveState( save );

			save["Fuel"] = Fuel;
			save["Resources"] = Resources;

			return true;
		}

		// ----------
		
		public override Vector2 GetShootPos() {
            if( PhysicsObject != null ) {
                Vector2 offset = Vector2.Transform( PhysicsObject.LocalCenter + new Vector2(0.75f,0f), Matrix.CreateRotationZ(Angle) );
                return Position + offset;
            }
            return Position;
		}

        public override void Update() {
            if( ControllingPlayer != null && PhysicsObject != null ) {
                UserCommand ucmd = ControllingPlayer.Input;

                Vector2 left = ucmd.LeftThumb;
                Vector2 right = ucmd.RightThumb;

                // Debug
                if (Fuel > 0)
                {
                    if (Input.IsKeyDown(Keys.Up))
                    {
                        left.Y += 1f;
                        Fuel -= MovementForce;
                    }
                    if (Input.IsKeyDown(Keys.Down))
                    {
                        left.Y -= 1f;
                        Fuel -= MovementForce;
                    }
                    if (Input.IsKeyDown(Keys.Right))
                    {
                        right.X += 1f;
                        Fuel -= TurningForce;
                    }
                    if (Input.IsKeyDown(Keys.Left))
                    {
                        right.X -= 1f;
                        Fuel -= TurningForce;
                    }
                }

                if( left.Length() > 0.3f ) {
                    Vector2 movement = new Vector2(
						(float)Math.Cos( Angle ) * MovementForce * left.Y,
						(float)Math.Sin( Angle ) * MovementForce * left.Y
					);

                    if( ucmd.LeftTrigger > 0.3f )
                        movement *= (BoostMultiplier * ucmd.LeftTrigger);
					
                    Fuel -= movement.Length();

                    PhysicsObject.ApplyForce( movement, PhysicsObject.WorldCenter );
                }

				if( right.Length() > 0.3f ) {
					float torque = -right.X * TurningForce;
					
                    if( ucmd.LeftTrigger > 0.3f )
                        torque *= (BoostMultiplier * ucmd.LeftTrigger);

                    Fuel -= torque;

                    PhysicsObject.ApplyTorque( torque );
				}

                if( ucmd.RightTrigger > 0.3f || Input.IsKeyDown(Keys.Space) ) {
                    DoFire();
                }
            }

			base.Update();
		}

		public virtual void DoFire() {
			if( Globals.GameTime - LastFireTime >= FireRate ) {
				FireProjectile( ProjectileType, GetShootPos() );
				LastFireTime = Globals.GameTime;
			}
		}

		// ----------

        public override bool OnCollision( Entity other, FarseerPhysics.Dynamics.Contacts.Contact contact ) {
            if( other is Planet && !(other is Sun) )
                DockedPlanet = (Planet)other;

            return base.OnCollision(other, contact);
        }

        public override void OnSeparation( Entity other ) {
			if( other is Planet && !(other is Sun) && DockedPlanet == other )
				DockedPlanet = null;

            base.OnSeparation(other);
        }

		public float FireRate { get; set; }
		public float LastFireTime { get; set; }
        public Type ProjectileType { get; set; }

        public float Fuel { get; set; }
        public float MaxFuel { get; set; }
		public float MovementForce { get; set; }
		public float TurningForce { get; set; }
		public float BoostMultiplier { get; set; }

        public int Resources { get; set; }
        public Planet DockedPlanet { get; set; }
    }
}
